/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Byte Array Comparer Class
 *      Compares two byte arrays for equivalence.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Collections;

namespace Adaptive.Foundation
{
    /// <summary>
    /// Compares two byte arrays for equivalence.
    /// </summary>
    [Serializable()]
    public sealed class ByteArrayComparer : IComparer
    {
        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <value>
        /// This is the default constructor.
        /// </value>
        public ByteArrayComparer() : base()
        {
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Performs a comparison of two byte arrays and returns a value indicating whether 
        /// one is less than, equal to or greater than the other.
        /// </summary>
        /// <param name="a">The first object to compare.</param>
        /// <param name="b">The second object to compare.</param>
        /// <returns>
        /// Less than zero if <i>a</i> is less than <i>b</i>b,
        /// Zero, if <i>a</i> equals <i>b</i>,
        /// Greater than zero if <i>a</i> is greater than <i>b</i>.
        /// </returns>
        public int Compare(object a, object b)
        {
            byte leftValue = 0;
            byte rightValue = 0;

            if ((a is byte[]) && (b is byte[]))
                return Compare((byte[])a, (byte[])b);

            else if ((a is byte) && (b is byte[]))
                return -1;

            else if ((a is byte) || (b is byte))
            {
                leftValue = Convert.ToByte(a);
                rightValue = Convert.ToByte(b);
                if (leftValue == rightValue)
                    return 0;
                else if (leftValue < rightValue)
                    return -1;
                else
                    return 1;
            }
            else
                return -1;
        }
        /// <summary>
        /// Performs a comparison of two byte arrays and returns a value indicating whether 
        /// one is less than, equal to or greater than the other.
        /// </summary>
        /// <param name="leftArray">The first object to compare.</param>
        /// <param name="rightArray">The second object to compare.</param>
        /// <returns>
		/// Less than zero if <i>leftArray</i> is less than <i>rightArray</i>,
        /// Zero, if <i>leftArray</i> equals <i>rightArray</i>,
		/// Greater than zero if <i>leftArray</i> is greater than <i>rightArray</i>.
        /// </returns>
        public int Compare(byte[] leftArray, byte[] rightArray)
        {
            int returnValue = 0;                //Return value.
            int count = 0;                      //Iteration counter.
            int length = 0;                     //Iteration limit.

            //If both are null, both are equal.
            if ((leftArray == null) && (rightArray == null))
                returnValue = 0;
            else
            {
                //If one is null and the other is not, the null array is less than the other.
                if (leftArray == null)
                    returnValue = -1;
                else if (rightArray == null)
                    returnValue = 1;
                else
                {
                    //The shortest array is less than the longer array.
                    if (leftArray.Length < rightArray.Length)
                        returnValue = -1;
                    else if (leftArray.Length > rightArray.Length)
                        returnValue = 1;
                    else
                    {
                        //With non-null arrays of the same size; compare the byte values from
                        //left to right.
                        returnValue = 0;
                        length = leftArray.Length;
                        do
                        {
                            if (leftArray[count] < rightArray[count])
                                returnValue = -1;
                            else if (leftArray[count] > rightArray[count])
                                returnValue = 1;
                            count++;
                        } while ((returnValue == 0) && (count < length));
                    }
                }
            }
            return returnValue;
        }
        /// <summary>
        /// Determines whether the specified <b>Object</b> is equal to the current <b>Object</b>.
        /// </summary>
        /// <param name="obj">
        /// The <see cref="Object"/> to compare with the current <b>Object</b>.
        /// </param>
        /// <returns>
        /// <b>true</b> if the specified <b>Object</b>. is equal to the current <b>Object</b>.; otherwise, <b>false</b>. 
        /// </returns>
        public override bool Equals(object obj)
        {
            return Equals((ByteArrayComparer)obj);
        }
        /// <summary>
        /// Determines whether the specified <b>ByteArrayComparer</b> is equal to the current <b>Object</b>.
        /// </summary>
        /// <param name="obj">
        /// The <see cref="ByteArrayComparer"/> to compare with the current <b>Object</b>.
        /// </param>
        /// <returns>
        /// <b>true</b> if the specified <b>Object</b>. is equal to the current <b>Object</b>.; otherwise, <b>false</b>. 
        /// </returns>
        public bool Equals(ByteArrayComparer obj)
        {
            bool returnValue = false;               //Return value.

            returnValue = ((obj != null) && (obj == this));
            return returnValue;
        }
        /// <summary>
        /// Determines whether the specified <b>Object</b> instances are considered equal. 
        /// </summary>
        /// <param name="objA">The first <see cref="Object"/> to compare.</param>
        /// <param name="objB">The second <see cref="Object"/> to compare. </param>
        /// <returns>
        /// <b>true</b> if <i>objA</i> is the same instance as <i>objB</i> or if both are 
        /// <b>null</b> references; otherwise, <b>false</b>.
        /// </returns>
        public new bool Equals(object objA, object objB)
        {
            bool returnValue = false;           //Return value.

            returnValue = ((objA == null) && (objB == null));
            if (!returnValue)
                returnValue = Equals((byte[])objA, (byte[])objB);

            return returnValue;
        }
        /// <summary>
        /// Determines whether the specified Object instances are considered equal. 
        /// </summary>
        /// <param name="leftArray">The first Object to compare.</param>
        /// <param name="rightArray">The second Object to compare. </param>
        /// <returns>
        /// <b>true</b> if <i>leftArray</i> is the same instance as <i>rightArray</i> or if both are 
        /// <b>null</b> references; otherwise, <b>false</b>.
        /// </returns>
        public bool Equals(byte[] leftArray, byte[] rightArray)
        {
            return (((leftArray == null) && (rightArray == null)) || (Compare(leftArray, rightArray) == 0));
        }
		/// <summary>
		/// Gets a hash code value for the current object instance.
		/// </summary>
		/// <returns>
		/// A hash code value.
		/// </returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
        #endregion
    }
}